import React from "react";
import { Toast } from "antd-mobile";
// import axios from "axios";
import { API } from "../../utils/api";

import NavHeader from "../../components/NavHeader";

import './index.scss'

// 导入BASE_URL
import { BASE_URL } from "../../utils/url"; 

// 导入List组件
import { List, AutoSizer } from 'react-virtualized'


const TITLE_HEIGHT = 36
const CITY_HEIGHT = 50

export default class CityList extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      cityData: [],
      cityObj: {},
      cityObjArr: [],
      currentCityName: '',
      hotCities: [],
      currIndex: 0
    }
    // 创建ref对象
    this.cityListComponent = React.createRef()
  }

  async getCityData() {
    let res = await API.get(`${BASE_URL}/area/city?level=1`)
    this.setState({
      cityData: res.data.body
    })
    this.sortAndDivideCityData()
  }

  // 获取当前定位城市名称
  getCurrentCity() {
    // ip定位获取当前位置信息
    var myCity = new window.BMapGL.LocalCity();
    // 根据当前城市名称获取城市信息
    myCity.get(res => {
      let currentCityName = res.name.slice(0, -1)
      this.setState({
        currentCityName,
      })
    })
  }

  // 获取热门城市数据
  async getHotCities() {
    let res = await API.get(`${BASE_URL}/area/hot`)
    let hotCities = []
    res.data.body.map(item => {
      return hotCities.push(item.label)
    })
    this.setState({
      hotCities
    })
  }
  

  // 对城市列表数据排序并分组
  sortAndDivideCityData() {
    let cityData = this.state.cityData

    // 城市列表根据首字母排序函数
    const sortByPinYin = (a, b) => {
      function helper(a, b, i) {
        if (!a[i]) return -1
        if (!b[i]) return 1
        if (a.charCodeAt(0) < b.charCodeAt(0)) {
          return -1
        } else if (a.charCodeAt(0) > b.charCodeAt(0)) {
          return 1
        } else {
          return helper(a, b, i+1)
        }
      }
      return helper(a.pinyin, b.pinyin, 0)
    }

    // 城市列表排序
    cityData = cityData.sort(sortByPinYin)
    // 城市列表根据首字母分组
    // 生成城市列表对象
    let cityObj = {}
    cityObj['#'] = []
    cityObj['hot'] = []
    cityData.map(item => {
      let firstLetter = item.pinyin[0],
      hotCities = this.state.hotCities
      if (!(firstLetter in cityObj)) {
        cityObj[firstLetter] = []
      }
      cityObj[firstLetter].push(item)

      if (item.label === this.state.currentCityName) {
        cityObj['#'].push(item)
      }

      if (hotCities.includes(item.label)) {
        cityObj['hot'].push(item)
      }
      return null
    })

    // 生成城市列表数组
    let cityObjArr = []
    for (let key in cityObj) {
      cityObjArr.push(key)
    }
    this.setState({cityObj, cityObjArr})

    return {cityObj, cityObjArr}
  }

  // react-virtualized函数 函数返回值表示最终渲染内容
  rowRenderer({
    key, // Unique key within array of rows
    index, // Index of row within collection
    isScrolling, // The List is currently being scrolled
    isVisible, // This row is visible within the List (eg it is not an overscanned row)
    style, // Style object to be applied to row (to position it)
  }) {
    // 获取城市索引数组
    const { cityObjArr, cityObj } = this.state
    let cityGroupKey = cityObjArr[index]

    return (
      <div key={key} style={style} className="single">
        <div className="title">{cityGroupKey === '#' ? '当前定位城市' : cityGroupKey === 'hot' ? '热门城市' : cityGroupKey.toUpperCase()}</div>
        {
          cityObj[cityObjArr[index]].map(item => {
            return (
              <div className="name" key={item.value} onClick={() => {this.changeCity(item)}}>{item.label}</div>
            )
          })
        }
      </div>
    );
  }

  // 动态计算每一个城市分组的高度
  calcHeight(index) {
    const { cityObjArr, cityObj } = this.state
    let len = cityObj[cityObjArr[index['index']]].length
    return CITY_HEIGHT*(len) + TITLE_HEIGHT
  }

  // 列表滚动函数
  onRowsRendered({ startIndex }) {
    if (this.state.currIndex !== startIndex) {
      this.setState({
        currIndex: startIndex
      })
    }
  }

  // 点击切换城市事件
  changeCity({ label, value }) {
    if (this.state.hotCities.includes(label)) {
      localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
      this.props.history.go(-1)
    } else {
      Toast.info('抱歉，当前没有所选城市信息!', 1.5, null, false)
    }
  }

  renderCitys() {
    let { cityObjArr, currIndex } = this.state
    return (
      // <div className="cityList">
      //   {
      //     cityObjArr.map(item => {
      //       return (
      //         <AntList key={item} renderHeader={() => { return /^[a-zA-Z]+$/.test(item) ? item.length > 1 ? '热门城市' : item[0].toUpperCase() : '当前定位城市'}} className="my-list">
      //           {
      //             cityObj[item].map((obj) => {
      //               return (
      //                 <AntList.Item key={obj.value}>{obj.label}</AntList.Item>
      //               )
      //             })
      //           }              
      //         </AntList>
      //       )
      //     })
      //   }
      // </div>
      <div className="cityList">
        <AutoSizer>
          {
            ({ width, height}) => {
              return (
              <List
                ref={this.cityListComponent}
                width={width}
                height={height}
                rowCount={cityObjArr.length}
                rowHeight={this.calcHeight.bind(this)}
                rowRenderer={this.rowRenderer.bind(this)}
                onRowsRendered={this.onRowsRendered.bind(this)}
                scrollToAlignment='start'
              />)
            }
          }
        </AutoSizer>

        <ul className="cityIndex">
          {
            // 问题：scrollToRow之能针对当前列表中已经渲染的部分实现精确跳转，对于还未渲染的部分会存在精确度问题
            // 解决：用measureAllRows方法提前计算每一行的高度，可以实现精确跳转
            cityObjArr.map((item, id) => {
              return <li key={item} className={currIndex === id ? 'currIndex' : ''} onClick={() => {
                this.cityListComponent.current.scrollToRow(id)
              }}>{id === 1 ? '热' : item.toUpperCase()}</li>
            })
          } 
        </ul>
      </div>
    )
  }

  async componentDidMount() {
    // 获取当前定位城市和热门城市数据
    this.getCurrentCity()
    this.getHotCities()
    await this.getCityData()
    // 问题：方法调用报错（Requested index -1 is outside of range 0..0）
    // 原因：由于getCityData方法为异步执行，因此measureAllRows执行时还没有城市列表数据，因此返回结果为-1
    // 解决：使用async-await保证getCityData先于measAllRows方法执行
    this.cityListComponent.current.measureAllRows()
  }

  render() {
    return (
      <div className='city'>
        {/* 顶部导航栏组件 */}
        <NavHeader>
          城市选择
        </NavHeader>
        { 
          this.renderCitys()
        }
      </div>
    );
  }
}
